package com.example.lock;

import org.I0Itec.zkclient.ZkClient;

import java.util.concurrent.CountDownLatch;

/**
 * Create with Intellij idea
 * User:mingtian
 * Date:2018/10/21
 * Time:22:28
 */
//将重复代码抽象到子类中(设计模式中模版方法设计模式)
public abstract class ZookeeperAbstractLock implements ExtLock {

    //连接ip地址端口
    private static final String connection = "127.0.0.1:2181";
    //连接zk客户端
    protected ZkClient zkClient = new ZkClient(connection);
    //创建节点
    protected String lockPath = "/lockPath";
    protected CountDownLatch countDownLatch = null;

    /*
     * 获取锁
     */
    @Override
    public void getLock() {
        //1.连接zkclient 在zk上创建节点/lock节点,节点类型为临时节点
        //2.如果节点创建成功，直接执行业务逻辑，如果失败 进行等待
        if (tryLock()) { //true 获取成功
            System.out.println("获取锁成功...");
        } else {
            //进行等待
            //3. 使用事件通知监听节点是否被删除，如果删除的话 重新进入获取锁的资源
            waitLock();
            getLock();//如果被删除  递归获取锁
        }

    }

    //如果创建节点失败 进行等待 使用事件通知监听该节点是否被删除，如果被删除的话重新获取锁资源
    abstract void waitLock();

    //获取锁的资源  如果获取锁成功返回true  如果失败返回false
    abstract boolean tryLock();

    /*
     *  释放锁
     */
    @Override
    public void unLock() {
        //当程序执行完毕之后，直接关闭连接
        if (zkClient != null) {
            zkClient.close();
            System.out.println("释放锁完毕...");
        }
    }
}
